<?php


namespace services\buss;


use common\components\Service;
use common\helpers\CommonHelper;
use common\helpers\RedisHelper;
use common\models\base\Department;
use common\models\base\Project;
use common\models\buss\CommonRelation;
use common\models\buss\Devices;
use common\models\buss\Scard;
use common\models\buss\ScardRecharge;
use common\models\member\Member;
use Exception;
use services\base\DepartmentService;
use services\log\LogMemberOpService;
use services\base\CommonRelationService;
use services\member\MemberService;
use Yii;

class ScardService extends Service
{
    /**
     * 手机卡列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function scardList(array $params, int $page, int $pageSize): array
    {
        $query = Scard::find()
            ->alias('s')
            ->select(['s.*', 'd.name devices_name'])
            ->leftJoin(CommonRelation::tableName() . ' cr', 'cr.relation_id = s.id and cr.type =' . CommonRelation::TYPE_DEVICES)
            ->leftJoin(Devices::tableName() . ' d', 'd.id = cr.primary_id and d.status in ('.Devices::STATUS_ENABLE.','. Devices::STATUS_INVALID.')')
            ->where([
                's.status' => [
                    Scard::STATUS_ENABLE,
                    Scard::STATUS_INVALID
                ],
//                's.project_id' => array_column(MemberService::getAllProjectListCondition(), 'value')
            ]);

        // 权限【项目、部门】
        $memberAuth = MemberService::getLoginMemberLimit();
        // 是超管直接跳过
        if ($memberAuth['super_type'] != Member::SUPER_TYPE_SUPER_ADMIN) {
            // 是否为项目管理员
            if ($memberAuth['admin_project_ids']) {
                $query->andWhere([
                    'or',
                    ['s.project_id' => $memberAuth['admin_project_ids']],// 是【一个或几个】项目管理员则查全项目数据
                    [
                        's.department_id' => $memberAuth['all_department_ids'],
                        's.project_id' => $memberAuth['member_project_ids'],
                        's.use_mid' => $memberAuth['all_member_ids'],
                    ]
                ]);
            } else {
                $query->andWhere([
                        's.department_id' => $memberAuth['all_department_ids'],
                        's.project_id' => $memberAuth['member_project_ids'],
                        's.use_mid' => $memberAuth['all_member_ids'],
                    ]);
            }
        }

        // 搜索手机号/ 备注
        if (isset($params['keywords']) && $params['keywords']) {
            if (is_numeric($params['keywords'])) {
                $query->andWhere(['like', 's.sim_card', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere(['like', 's.remark', $params['keywords']]);
            }
        }
        // 项目
        if (isset($params['project_id']) && $params['project_id']) {
            $query->andWhere(['s.project_id' => $params['project_id']]);
        }
        // 部门
        if (isset($params['department_id']) && $params['department_id']) {
            $allIds = $params['department_id'];
            $department = RedisHelper::getDepartment($params['department_id']);
            if ($department->data_level == Department::DATA_LEVEL_DEPARTMENT_ALL) {
                $childDepartmentList = DepartmentService::getChildDepartmentList($department->tree_id);
                $allIds = array_merge([$department->id], array_column($childDepartmentList, 'id'));
            }
            $query->andWhere(['s.department_id' => $allIds]);
        }
        // 认证人
        if (isset($params['authenticator_user']) && $params['authenticator_user']) {
            if ($params['authenticator_user'] == '无认证人') {
                $query->andWhere(['s.authenticator_user' => '']);
            } else {
                $query->andWhere(['s.authenticator_user' => $params['authenticator_user']]);
            }
        }
        // 使用人
        if (isset($params['use_mid']) && $params['use_mid']) {
            $query->andWhere(['s.use_mid' => $params['use_mid']]);
        }
        $list = $this->getListPageRes($query, $page, $pageSize, ['s.status' => SORT_DESC, 's.id' => SORT_DESC]);
        foreach ($list['list'] as &$val) {
            $project = $val['project_id'] ? RedisHelper::getProject($val['project_id']) : '';
            $val['project_name'] = $project && $project->status != Project::STATUS_DELETE ? $project->project_name : '';
//            $department = $val['department_id'] ? RedisHelper::getDepartment($val['department_id']) : '';
//            $val['department_name'] = $department && $department->status != Department::STATUS_DELETE ? $department->department_name : '';
            $departmentName = DepartmentService::getParent($val['department_id']);
            $val['department_name'] = implode(' / ', $departmentName);
            $member = $val['use_mid'] ? RedisHelper::getMember($val['use_mid']) : '';
            $val['use_mname'] = $member && $member->status != Member::STATUS_DELETE ? $member->realname : '';
            $val['status_name'] = Scard::$statuss[$val['status']] ?? '';
            $val['sim_telecom_name'] = Scard::$simTelecoms[$val['sim_telecom']] ?? '';
        }
        return $list;
    }

    /**
     * 认证人下拉筛选项
     * @return array[]
     */
    public static function getAuthenticatorCondition(): array
    {
        $list = Scard::find()
            ->select(['authenticator_user label'])
            ->where(['status' => [Scard::STATUS_ENABLE, Scard::STATUS_INVALID]])
            ->andWhere(['!=', 'authenticator_user', ''])
            ->groupBy('authenticator_user')
            ->asArray()
            ->all();
        foreach ($list as &$val) {
            $val['value'] = $val['label'];
        }
        return array_values($list);
    }

    /**
     * 使用人下拉筛选项
     * @return array[]
     */
    public static function getUseMemberCondition(): array
    {
        $query = Scard::find()
            ->alias('s')
            ->select(['s.use_mid value', 'm.realname label'])
            ->leftJoin(Member::tableName() . ' m', 'm.id = s.use_mid')
            ->where(['s.status' => [Scard::STATUS_ENABLE, Scard::STATUS_INVALID]]);

        $memberAuth = MemberService::getLoginMemberLimit();
        // 是超管直接跳过
        if ($memberAuth['super_type'] != Member::SUPER_TYPE_SUPER_ADMIN) {
            // 是否为项目管理员
            if ($memberAuth['admin_project_ids']) {
                $query->andWhere([
                    'or',
                    ['s.project_id' => $memberAuth['admin_project_ids']],// 是【一个或几个】项目管理员则查全项目数据
                    ['s.use_mid' => $memberAuth['all_member_ids']]
                ]);
            } else {
                $query->andWhere(['s.use_mid' => $memberAuth['all_member_ids']]);
            }
        }
        return $query->andWhere(['!=', 's.use_mid' , 0])
            ->groupBy('s.use_mid')
            ->asArray()
            ->all();
    }

    /**
     * 状态下拉筛选项
     * @return array[]
     */
    public static function getStatusCondition(): array
    {
        return [
            ['value' => Scard::STATUS_ENABLE, 'label' => Scard::$statuss[Scard::STATUS_ENABLE]],
            ['value' => Scard::STATUS_INVALID, 'label' => Scard::$statuss[Scard::STATUS_INVALID]],
        ];
    }

    /**
     * 运营商下拉筛选项
     * @return array[]
     */
    public static function getSimTelecomsCondition(): array
    {
        return [
            ['value' => Scard::SIM_YD, 'label' => Scard::$simTelecoms[Scard::SIM_YD]],
            ['value' => Scard::SIM_LT, 'label' => Scard::$simTelecoms[Scard::SIM_LT]],
            ['value' => Scard::SIM_DX, 'label' => Scard::$simTelecoms[Scard::SIM_DX]],
            ['value' => Scard::SIM_GD, 'label' => Scard::$simTelecoms[Scard::SIM_GD]]
        ];
    }

    /**
     * 手机号下拉筛选项【未被绑定的手机号】
     * @param int $devicesId
     * @return array
     */
    public static function getScardEditCondition(int $devicesId): array
    {
        // 已绑定手机卡IDs
        $commonRelations = CommonRelationService::getCommonRelationListByType(CommonRelation::TYPE_DEVICES);
        $bindIds = [];
        foreach ($commonRelations as $commonRelation) {
            if ($devicesId && $commonRelation->primary_id == $devicesId) {// 编辑设备【不排除自身】
                continue;
            }
            $bindIds[] = $commonRelation->relation_id;
        }
        $query = Scard::find()
            ->select(['id value', 'sim_card label'])
            ->where(['status' => Scard::STATUS_ENABLE]);
        if ($bindIds) {
            $query->andWhere(['not in', 'id', $bindIds]);
        }
        return $query->asArray()->all();
    }

    /**
     * 更新手机卡
     * @throws Exception
     */
    public function updateScard(array $params)
    {
        $scard = new Scard();
        $scenario = 'create';
        $oldScard = null;
        // 是否为编辑，编辑判断排除当前ID
        $whereId = [];
        if ($params['id']) {
            $whereId = ['!=', 'id', $params['id']];
            // 手机卡表
            $oldScard = self::getData($params['id']);
            $scard = Scard::findOne($params['id']);
            $scenario = 'edit';
        }
        // 判断名称是否存在
        $check = Scard::find()
            ->select(['id'])
            ->where([
                'sim_card' => $params['sim_card'],
                'status' => [Scard::STATUS_ENABLE, Scard::STATUS_INVALID]
            ])
            ->andWhere($whereId)
            ->one();
        if ($check) {
            return CommonHelper::api(422, '手机卡已存在');
        }

        $scard->sim_card = $params['sim_card'];
        $scard->department_id = $params['department_id'];
        $scard->project_id = $params['project_id'];
        $scard->sim_telecom = $params['sim_telecom'];
        $scard->authenticator_user = $params['authenticator_user'];
        $scard->remark = $params['remark'] ?: '';
        $scard->status = $params['status'] ?? Scard::STATUS_ENABLE;
        $scard->use_mid = isset($params['use_mid']) && $params['use_mid'] ? $params['use_mid'] : 0;
        $scard->operation_id = Yii::$app->user->identity->member_id;
        $scard->operation_name = Yii::$app->user->identity->member->realname;
        $scard->saveAndCheckResult();

        // 添加日志
        LogMemberOpService::createScardLog($scenario, $scard, $oldScard);

        return ['id' => $scard->id];
    }

    /**
     * 手机卡
     * @param int $id
     * @return Scard|null
     */
    public static function getData(int $id): ?Scard
    {
        return Scard::findOne($id);
    }

    /**
     * 手机卡删除
     */
    public function deleteScard(array $params): array
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 更新手机卡状态为-1
            Scard::updateAll([
                'status' => Scard::STATUS_DELETE,
                'operation_id' => Yii::$app->user->identity->member_id,
                'operation_name' => Yii::$app->user->identity->member->realname,
                'updated_at' => time()
            ], ['id' => $params['id']]);

            // 设备解绑手机卡
            CommonRelation::deleteAll(['relation_id' => $params['id'], 'type' => CommonRelation::TYPE_DEVICES]);

            // 添加日志
            LogMemberOpService::createScardLog('delete',  self::getData($params['id']));
            $transaction->commit();
            return ['id' => $params['id']];
        } catch (Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 充值列表
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function rechargeList(array $params, int $page, int $pageSize): array
    {
        $query = ScardRecharge::find()->where(['scard_id' => $params['id'], 'status' => Scard::STATUS_ENABLE]);
        // 充值开始时间
        if (isset($params['recharge_stime']) && $params['recharge_stime']) {
            $query->andWhere(['>=', 'recharge_time', strtotime($params['recharge_stime'])]);
        }
        // 充值结束时间
        if (isset($params['recharge_etime']) && $params['recharge_etime']) {
            $query->andWhere(['<=', 'recharge_time', strtotime($params['recharge_etime'] . ' 23:59:59')]);
        }
        $list = $this->getListPageRes($query, $page, $pageSize, ['status' => SORT_DESC, 'recharge_time' => SORT_DESC]);
        foreach ($list['list'] as &$val) {
            $val['recharge_time_str'] = $val['recharge_time'] ? date('Y-m-d', $val['recharge_time']) : '';
        }
        return $list;
    }

    /**
     * 新增充值
     */
    public function createRecharge(array $params): array
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 新增充值记录
            $recharge = new ScardRecharge();
            $recharge->scard_id = $params['scard_id'];
            $recharge->recharge_money = $params['recharge_money'];
            $recharge->recharge_time = strtotime($params['recharge_time']);
            $recharge->remark = $params['recharge_remark'] ?: '';
            $recharge->status = $params['status'] ?? ScardRecharge::STATUS_ENABLE;
            $recharge->operation_id = Yii::$app->user->identity->member_id;
            $recharge->operation_name = Yii::$app->user->identity->member->realname;
            $recharge->saveAndCheckResult();

            // 添加日志
            LogMemberOpService::createScardLog('recharge', null, null, $recharge);
            // 更新手机套餐
            $this->updateRechargeRemark($params);

            $transaction->commit();
            return ['scard_id' => $recharge->scard_id];
        } catch (Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 新增/编辑手机套餐
     */
    public function updateRechargeRemark(array $params): array
    {
        $scard = Scard::findOne(['id' => $params['scard_id']]);
        if ($scard->recharge_remark == $params['recharge_remark']) {
            return [];
        }
        $scard->recharge_remark = $params['recharge_remark'];
        $scard->operation_id = Yii::$app->user->identity->member_id;
        $scard->operation_name = Yii::$app->user->identity->member->realname;
        $scard->saveAndCheckResult();
        return ['id' => $scard->id];
    }

    /**
     * 删除充值记录
     * @param int $rechargeId
     * @return int
     * @throws Exception
     */
    public function deleteRecharge(int $rechargeId): int
    {
        $recharge = ScardRecharge::findOne($rechargeId);
        $scard = Scard::findOne($recharge->scard_id);
        // 添加日志
        LogMemberOpService::createScardLog('delete_recharge', $scard, null, $recharge);
        return ScardRecharge::deleteAll(['id' => $rechargeId]);
    }

    /**
     * 人员删除部门解除绑定人员数据
     * @param int $memberId
     * @param $departmentIds
     * @return void
     */
    public static function clearUseMid(int $memberId, $departmentIds): void
    {
        Scard::updateAll(['use_mid' => 0], ['department_id' => $departmentIds, 'use_mid' => $memberId]);
    }
}
